#include <iostream>
#include <cstring>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "../libs/ikcp.h"

#define SERVER_PORT 8888
#define BUFFER_SIZE 1024

int main() {
	// 创建UDP套接字
	int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
	if (sockfd == -1) {
		std::cerr << "Create socket failed" << std::endl;
		return -1;
	}

	// 设置服务器地址结构体
	struct sockaddr_in serverAddr;
	serverAddr.sin_family      = AF_INET;
	serverAddr.sin_port        = htons(SERVER_PORT);
	serverAddr.sin_addr.s_addr = INADDR_ANY;

	// 绑定套接字到指定地址和端口
	if (::bind(sockfd, (struct sockaddr *) &serverAddr, sizeof(serverAddr)) == -1) {
		std::cerr << "Bind socket failed" << std::endl;
		close(sockfd);
		return -1;
	}

	// 创建KCP对象
	ikcpcb *kcp = ikcp_create(0x11223344, (void *) sockfd);
	kcp->output = [](const char *buf, int len, ikcpcb *kcp, void *user) {
		int                sockfd = (int) user;
		struct sockaddr_in clientAddr;
		socklen_t          addrLen = sizeof(clientAddr);
		sendto(sockfd, buf, len, 0, (struct sockaddr *) &clientAddr, addrLen);
	};

	char               buffer[BUFFER_SIZE];
	struct sockaddr_in clientAddr;
	socklen_t          addrLen = sizeof(clientAddr);

	while (true) {
		// 接收UDP数据包
		int recvLen = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *) &clientAddr, &addrLen);
		if (recvLen > 0) {
			// 输入数据到KCP
			ikcp_input(kcp, buffer, recvLen);

			// 处理KCP消息
			while (true) {
				int peekLen = ikcp_peeksize(kcp);
				if (peekLen < 0) {
					break;
				}
				char *recvData    = new char[peekLen];
				int   recvDataLen = ikcp_recv(kcp, recvData, peekLen);
				if (recvDataLen > 0) {
					std::cout << "Received message from client: " << recvData << std::endl;

					// 发送响应消息
					const char *response = "Message received successfully";
					ikcp_send(kcp, response, strlen(response));
				}
				delete[] recvData;
			}

			// 更新KCP状态
			ikcp_update(kcp, iclock());
		}
	}

	// 释放KCP对象和关闭套接字
	ikcp_release(kcp);
	close(sockfd);

	return 0;
}
